package com.geovis.emergency.spd.biz.basic.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geovis.common.core.constant.CommonConstants;
import com.geovis.emergency.spd.biz.basic.mapper.BasicShareDocMapper;
import com.geovis.emergency.spd.biz.basic.mapper.BasicShareFolderMapper;
import com.geovis.emergency.spd.biz.basic.service.IBasicShareDocService;
import com.geovis.emergency.spd.biz.pc.mapper.PcDrillMapper;
import com.geovis.emergency.spd.biz.system.service.ISystemFileService;
import com.geovis.emergency.spd.biz.system.wrapper.ForestNodeMerger;
import com.geovis.emergency.spd.entity.basic.entity.BasicShareDoc;
import com.geovis.emergency.spd.entity.basic.entity.BasicShareFolder;
import com.geovis.emergency.spd.entity.basic.pojo.enums.ShareDocFileTypeEnum;
import com.geovis.emergency.spd.entity.basic.pojo.vo.ShareDocTreeVO;
import com.geovis.emergency.spd.entity.pc.entity.PcDrill;
import com.geovis.emergency.spd.entity.pc.pojo.enums.StatusEnum;
import com.geovis.emergency.spd.entity.system.constant.SystemFileBusinessConstant;
import com.geovis.emergency.spd.entity.system.entity.SystemFile;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileUploadDTO;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * <p>
 * 基础模块-共享文档 服务实现类
 * </p>
 *
 * @author Lonsho
 * @since 2022-07-12
*/

@Service
@RequiredArgsConstructor
@Slf4j
public class BasicShareDocServiceImpl extends ServiceImpl<BasicShareDocMapper, BasicShareDoc> implements IBasicShareDocService {

    private final BasicShareFolderMapper basicShareFolderMapper;
    private final PcDrillMapper pcDrillMapper;

    private final ISystemFileService systemFileService;

    @Override
    public BasicShareFolder getOrCreateRootFolder(String drillId) {
        LambdaQueryWrapper<BasicShareFolder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrUtil.isBlank(drillId), BasicShareFolder::getFolderId, CommonConstants.TREE_ROOT_CODE);
        queryWrapper.eq(StrUtil.isNotBlank(drillId), BasicShareFolder::getPcDrillId, drillId);
        queryWrapper.last("limit 1");
        BasicShareFolder folder = basicShareFolderMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNull(folder)) {
            folder = new BasicShareFolder();
            folder.setFolderId(CommonConstants.TREE_ROOT_CODE);
            folder.setIsRoot(StatusEnum.TRUE.getCode());
            folder.setPcDrillId(drillId);
            folder.setName("根目录");
            if (StrUtil.isNotBlank(drillId)) {
                PcDrill pcDrill = pcDrillMapper.selectById(drillId);
                if (ObjectUtil.isNotNull(pcDrill)) {
                    //演练根目录
                    BasicShareFolder rootFolder = getOrCreateRootFolder(null);
                    folder.setFolderId(rootFolder.getId());
                    folder.setName(pcDrill.getName() + "共享文档");
                }
            }
            basicShareFolderMapper.insert(folder);
        }
        return folder;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShareDocTreeVO uploadFileInFolder(MultipartFile file, String folderId, String pcDrillId) {
        if (ObjectUtil.isNull(folderId)) {
            BasicShareFolder folder = getOrCreateRootFolder(pcDrillId);
            folderId = folder.getId();
        }
        SystemFileUploadDTO uploadDTO = new SystemFileUploadDTO();
        uploadDTO.setFile(file);
        uploadDTO.setRelatedId(pcDrillId);
        uploadDTO.setType(SystemFileBusinessConstant.TYPE_OSS_SHARE_DOC);
        SystemFile systemFile = systemFileService.upload(uploadDTO);
        Assert.notNull(systemFile,"上传失败");
        BasicShareDoc shareDoc = new BasicShareDoc();
        shareDoc.setFileType(systemFile.getContentType());
        shareDoc.setFileName(systemFile.getName());
        shareDoc.setFileExt(systemFile.getExtName());
        shareDoc.setFileId(systemFile.getId());
        shareDoc.setFileSize(systemFile.getSize());
        shareDoc.setPcDrillId(pcDrillId);
        shareDoc.setFolderId(folderId);
        save(shareDoc);
        ShareDocTreeVO shareDocTreeVO = BeanUtil.toBean(shareDoc, ShareDocTreeVO.class);
        shareDocTreeVO.setName(shareDoc.getFileName());
        shareDocTreeVO.setParentId(folderId);
        shareDocTreeVO.setType(ShareDocFileTypeEnum.FILE.getCode());
        return shareDocTreeVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ShareDocTreeVO> uploadFilesWithFolder(List<MultipartFile> files, String folderName, String folderId, String pcDrillId) {
        LambdaQueryWrapper<BasicShareFolder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BasicShareFolder::getName, folderName);
        queryWrapper.eq(StrUtil.isNotBlank(pcDrillId), BasicShareFolder::getPcDrillId, pcDrillId);
        if (ObjectUtil.isNotNull(folderId)) {
            queryWrapper.eq(BasicShareFolder::getFolderId, folderId);
        }
        queryWrapper.last("limit 1");
        //是否已经创建文件夹文件夹
        BasicShareFolder folder = basicShareFolderMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNull(folder)) {
            folder = new BasicShareFolder();
            folder.setName(folderName);
            if (ObjectUtil.isNotNull(folderId)) {
                folder.setFolderId(folderId);
            } else {
                BasicShareFolder rootFolder = getOrCreateRootFolder(pcDrillId);
                //如果没有文件夹id，那需要把文件上传的到根目录下
                folder.setFolderId(rootFolder.getId());
            }
            folder.setIsRoot(StatusEnum.FALSE.getCode());
            folder.setPcDrillId(pcDrillId);
            basicShareFolderMapper.insert(folder);
        }
        String finalFolderId = folder.getId();
        List<BasicShareDoc> shareDocList = Lists.newArrayList();
        for (MultipartFile file : files) {
            SystemFileUploadDTO uploadDTO = new SystemFileUploadDTO();
            uploadDTO.setFile(file);
            uploadDTO.setRelatedId(pcDrillId);
            uploadDTO.setType(SystemFileBusinessConstant.TYPE_OSS_SHARE_DOC);
            SystemFile systemFile = systemFileService.upload(uploadDTO);
            if (ObjectUtil.isNotNull(systemFile)) {
                BasicShareDoc shareDoc = new BasicShareDoc();
                shareDoc.setFileName(systemFile.getName());
                shareDoc.setFileExt(systemFile.getExtName());
                shareDoc.setFileType(systemFile.getContentType());
                shareDoc.setFileId(systemFile.getId());
                shareDoc.setFileSize(systemFile.getSize());
                shareDoc.setFolderId(finalFolderId);
                shareDoc.setPcDrillId(pcDrillId);
                shareDocList.add(shareDoc);
            }
        }
        if (CollectionUtil.isNotEmpty(shareDocList)) {
            saveBatch(shareDocList);
        }
        return createTree(folder,shareDocList);
    }

    private List<ShareDocTreeVO> createTree(BasicShareFolder folder, List<BasicShareDoc> ossShareDocList) {
        ShareDocTreeVO shareDocTreeFolderVO = new ShareDocTreeVO();
        shareDocTreeFolderVO.setId(folder.getId());
        shareDocTreeFolderVO.setName(folder.getName());
        shareDocTreeFolderVO.setParentId(folder.getFolderId());
        shareDocTreeFolderVO.setFileType(ShareDocFileTypeEnum.FOLDER.getCode());
        List<ShareDocTreeVO> shareDocTreeVOList= Lists.newArrayList(shareDocTreeFolderVO);
        for (BasicShareDoc shareDoc : ossShareDocList) {
            ShareDocTreeVO shareDocTreeVO = BeanUtil.toBean(shareDoc, ShareDocTreeVO.class);
            shareDocTreeVO.setName(shareDoc.getFileName());
            shareDocTreeVO.setParentId(shareDoc.getFolderId());
            shareDocTreeVO.setType(ShareDocFileTypeEnum.FILE.getCode());
            shareDocTreeVOList.add(shareDocTreeVO);
        }
        return ForestNodeMerger.merge(shareDocTreeVOList);
    }
}
